﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common.UI.Report.Views.Interfaces;
using Common.Model;
using System.ComponentModel;
using Common.ServiceLogic;
using Microsoft.Practices.Composite.Presentation.Commands;
using System.Windows;
using Microsoft.Practices.Composite.Events;

namespace Common.UI.Report.Views
{
    public class ReportPresentationModel<V, C, S> : IReportPresentationModel<V, C, S>, INotifyPropertyChanged
        where V : ViewEntity
        where C : CriteriaEntity
        where S : IGenericReportServiceLogic<V, C>, new()
    {

        public ReportPresentationModel(IFilterView filterView, IListView listView)
        {
            this.InitializeFilterPresentationModel(filterView);
            this.InitializeListPresentationModel(listView);
        }

        #region Filter

        C _lastCriteria;
        public C LastCriteria
        {
            get { return _lastCriteria; }
            set { _lastCriteria = value; }
        }

        public event SearchCalledEventHandler SearchCalled;

        public IFilterView FilterView
        {
            get;
            set;
        }

        public DelegateCommand<Object> SearchCommand
        {
            get;
            set;
        }

        public C CriteriaEntity { get; set; }

        public void InitializeFilterPresentationModel(IFilterView view)
        {
            this.FilterView = view;
            this.FilterView.Model = this;

            this.AddFilterCommands();
        }

        private void AddFilterCommands()
        {
            this.SearchCommand = new DelegateCommand<object>(ExecuteSearch, CanExecuteSearch);
            this.AddFilterCustomCommands();
        }

        protected virtual void AddFilterCustomCommands()
        {

        }


        private void ExecuteSearch(Object arg)
        {
            if (this.ValidateFilter())
            {
                if (SearchCalled != null)
                {
                    SearchCalled(this, new DataEventArgs<CriteriaEntity>(this.CriteriaEntity));
                }
                this.LoadList(this.CriteriaEntity);
                this.LastCriteria = this.CriteriaEntity;
            }
        }

        private bool ValidateFilter()
        {
            return this.FilterView.Validate();
        }

        private Boolean CanExecuteSearch(Object arg)
        {
            return true;
        }


        public void LoadCriteria(C criteriaEntity)
        {
            CriteriaEntity = criteriaEntity;
        }
        #endregion

        #region List

        public IListView ListView
        {
            get;
            set;
        }

        IGenericReportServiceLogic<V, C> _reportManager;
        public IGenericReportServiceLogic<V, C> ReportManager
        {
            get
            {
                if (_reportManager == null)
                {
                    _reportManager = new S();
                }
                return _reportManager;
            }
        }

        Object _list;
        public Object List
        {
            get
            {
                return _list;
            }
            set
            {
                _list = value;
                OnPropertyChanged("List");
            }
        }

        public DelegateCommand<Object> ShowReportCommand
        {
            get;
            set;
        }


        public Boolean AllowPrint
        {
            get;
            set;
        }
        public Boolean AllowExport
        {
            get;
            set;
        }

        public void InitializeListPresentationModel(IListView view)
        {
            this.ListView = view;
            this.ListView.Model = this;

            this.AddListCommands();
        }

        private void AddListCommands()
        {
            this.ShowReportCommand = new DelegateCommand<object>(ExecuteShowReport, CanExecuteShowReport);

            this.AddListCustomCommands();
        }

        protected virtual void AddListCustomCommands()
        {

        }

        protected void AddListCustomCommand(DelegateCommand<object> command, string text)
        {
            this.ListView.AddCustomCommand(command, text);
        }



        private void ExecuteShowReport(Object arg)
        {
            this.ShowReport();
        }

        private Boolean CanExecuteShowReport(Object arg)
        {
            return true;
        }


        public void LoadList(C criteriaEntity)
        {
            List = ReportManager.ReadViewsByCriteria(criteriaEntity);
        }

        #region IListPresentationModel<S,E,C,EV> Members

        public void AddColumnDefinition(String columnName, String header)
        {
            this.ListView.AddColumnDefinition(columnName, header);
        }

        #endregion

        public void ShowReport()
        {
            this.ListView.ShowReport(this.GetReportPath(), this.GetDataSourceName(), this.GetData(), this.GetParameters(), AllowExport, AllowPrint);
        }

        protected virtual List<ReportParameters> GetParameters()
        {
            return new List<ReportParameters>();
        }

        protected virtual object GetData()
        {
            return this.List;
        }

        protected virtual string GetDataSourceName()
        {
            return string.Empty;
        }

        protected virtual string GetReportPath()
        {
            return string.Empty;
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(String propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

    }
}